#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "../../ImageAcquisitor/ImageAcquisitor/global.h"

#include <QSettings>
#include <QSqlDatabase>
#include <QSqlError>
#include <QDebug>
#include <QProcess>
#include <QLocalSocket>

MainWindow::MainWindow(QWidget *parent) :
    view(new QProcess(this)),
    acq(new QProcess(this)),
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setupConnection();
    connectToDb();
    on_toolBtnGrp_buttonClicked(ui->findBtn);
    on_studyView_selectedRows(QList<int>());
}

MainWindow::~MainWindow()
{
    view->terminate();
    acq->terminate();
    view->waitForFinished(3000);
    acq->waitForFinished(3000);
    delete ui;
}

void MainWindow::setupConnection()
{
    connect(ui->wlistWidget, SIGNAL(startStudy(QString)), this, SLOT(on_startStudy(QString)));
    connect(ui->studyWidget, SIGNAL(startAcq(QString)), this, SLOT(on_startStudy(QString)));
    connect(ui->studyWidget, SIGNAL(viewStudy(QString)), this, SLOT(on_viewStudy(QString)));
}

void MainWindow::showMessage(const QString &msg)
{
    ui->statusBar->showMessage(msg);
}

void MainWindow::on_toolBtnGrp_buttonClicked(QAbstractButton *b)
{
    if (ui->acquisitBtn == b) {
        if (ui->studyWidget->isVisible()) ui->studyWidget->onStartAcq();
    } else if (ui->viewBtn == b) {
        ui->studyWidget->onViewStudy();
    } else {
        ui->wlistWidget->setVisible(false);
        ui->studyWidget->setVisible(false);
        ui->reportWidget->setVisible(false);
        ui->importWidget->setVisible(false);
        ui->exportWidget->setVisible(false);
        ui->settingsWidget->setVisible(false);
        ui->aboutWidget->setVisible(false);

        if (ui->wlistBtn == b) {
            ui->wlistWidget->setVisible(true);
        } else if (ui->findBtn == b) {
            ui->studyWidget->setVisible(true);
        } else if (ui->reportBtn == b) {
            ui->reportWidget->setVisible(true);
        } else if (ui->importBtn == b) {
            ui->importWidget->setVisible(true);
        } else if (ui->exportBtn == b) {
            ui->exportWidget->setVisible(true);
        } else if (ui->settingsBtn == b) {
            ui->settingsWidget->setVisible(true);
        } else if (ui->helpBtn == b) {
            ui->aboutWidget->setVisible(true);
        }
    }
}

void MainWindow::on_studyView_selectedRows(const QList<int> rows)
{
    ui->acquisitBtn->setEnabled(rows.size() == 1);
    ui->viewBtn->setEnabled(rows.size() == 1);
    ui->reportBtn->setEnabled(rows.size() == 1);
    ui->exportBtn->setEnabled(rows.size() > 0);
}

void MainWindow::on_startStudy(const QString &studyUid)
{
    if (acq->state() == QProcess::NotRunning) {
        acq->start("ImageAcquisitor.exe", QStringList()<<studyUid);
        if (acq->waitForStarted(3000)) {
            qDebug() << tr("Starting acquisitor...");
        } else {
            qWarning() << tr("Start acquisitor failed.");
        }
    } else {
        QLocalSocket *s = new QLocalSocket;
        connect(s, SIGNAL(disconnected()), s, SLOT(deleteLater()));
        s->connectToServer("ImageAcquisitor");
        if (s->waitForConnected(3000)) {
            s->write(studyUid.toLatin1());
            if (s->waitForBytesWritten(1000)) {
                qDebug() << tr("Start acquisit: ") + studyUid;
            } else {
                qWarning() << tr("Write local socket failed: timed out.");
            }
        } else {
            qWarning() << tr("Connect to acquisitor failed: ") + s->errorString();
        }
    }
}

void MainWindow::on_viewStudy(const QString &studyUid)
{
    if (view->state() == QProcess::NotRunning) {
        view->start("DicomViewer.exe", QStringList()<<studyUid);
        if (view->waitForStarted(3000)) {
            qDebug() << tr("Starting viewer...");
        } else {
            qWarning() << tr("Start viewer failed.");
        }
    } else {
        QLocalSocket *s = new QLocalSocket;
        connect(s, SIGNAL(disconnected()), s, SLOT(deleteLater()));
        s->connectToServer("DicomViewer");
        if (s->waitForConnected(3000)) {
            s->write(studyUid.toLatin1());
            if (s->waitForBytesWritten(1000)) {
                qDebug() << tr("Start view: ") + studyUid;
            } else {
                qWarning() << tr("Write local socket failed: timed out.");
            }
        } else {
            qWarning() << tr("Connect to viewer failed: ") + s->errorString();
        }
    }
}

bool MainWindow::connectToDb()
{
    if (QSqlDatabase::database().isOpen())
        return true;

    QSettings s(QCoreApplication::applicationDirPath() + "/"LOCAL_NETWORK_CONFIG, QSettings::IniFormat);
    s.setIniCodec(QSETTINGS_CODEC_NAME);
    QString t = s.value(NETWORK_DBMS_TYPE).toString();
    QSqlDatabase d = QSqlDatabase::addDatabase(t);
    if (d.isValid()) {
        QString host = s.value(NETWORK_DBMS_HOST).toString();
        int port = s.value(NETWORK_DBMS_PORT).toInt();
        QString name = s.value(NETWORK_DBMS_NAME).toString();
        QString user = s.value(NETWORK_DBMS_USER).toString();
        QString pwd = s.value(NETWORK_DBMS_PWD).toString();

        d.setHostName(host);
        d.setPort(port);
        d.setDatabaseName(name);
        d.setUserName(user);
        d.setPassword(pwd);
        if (d.open()) {
            qDebug() << "Open database ok";
            return true;
        } else {
            qCritical() << "Open database failed: " + d.lastError().text();
        }
    } else {
        qCritical() << d.lastError().text();
    }
    return false;
}
